package com.vcredit.creditcat.manager;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.dubbo.config.annotation.Service;
import com.vcredit.creditcat.api.ICreditCatProcessManager;
import com.vcredit.creditcat.model.Ability;
import com.vcredit.creditcat.model.AuthItem;
import com.vcredit.creditcat.model.AuthProccess;
import com.vcredit.creditcat.model.CustAbility;
import com.vcredit.creditcat.model.CustDimension;
import com.vcredit.creditcat.model.ItemDimension;
import com.vcredit.creditcat.service.AbilityService;
import com.vcredit.creditcat.service.AuthItemService;
import com.vcredit.creditcat.service.AuthProccessService;
import com.vcredit.creditcat.service.CustAbilityService;
import com.vcredit.creditcat.service.CustDimensionService;
import com.vcredit.creditcat.service.ItemDimensionService;
import com.vcredit.creditcat.util.ConcurrentDateUtil;
import com.vcredit.framework.annotation.Log;

@Service(protocol = { "protocol1" }, version = "1.0")
public class CreditCatProcessManager implements ICreditCatProcessManager {
	@Autowired
	private AuthProccessService authProccessService;
	@Autowired
	private CustAbilityService custAbilityService;
	@Autowired
	private AbilityService abilityService;
	@Autowired
	private ItemDimensionService itemDimensionService;
	@Autowired
	private AuthItemService authItemService;
	@Autowired
	private CustDimensionService custDimensionService;

	@Log
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public void itemDone(AuthItem item, Long processId) throws Exception {
		AuthItem authItem = authItemService.getItemByCode(item.getAuthCode());
		AuthProccess authProcess = authProccessService.findByIdForUpdate(processId);
		if ((authProcess.getSuccessCode() & authItem.getAuthCode()) == authItem.getAuthCode()) {
			return;
		}
		int successCode = authProcess.getSuccessCode() | authItem.getAuthCode();
		authProcess.setSuccessCode(successCode);
		authProccessService.updateProcess(authProcess);
		//特权与认证项不再关联
/*		Map<Long, Ability> NotGetAbilityMap = findNotGetAbility(authProcess.getCustId());
		List<CustAbility> custAbilityList = new ArrayList<CustAbility>();
		for (Ability ability : NotGetAbilityMap.values()) {
			if ((successCode & ability.getMinCode()) == ability.getMinCode()) {
				CustAbility custAbility = new CustAbility();
				custAbility.setCustId(authProcess.getCustId());
				custAbility.setAbilityId(ability.getAbilityId());
				custAbility.setAbilityGettime(new Date());
				custAbilityList.add(custAbility);
			}
		}
		if (!custAbilityList.isEmpty())
			custAbilityService.batchInsert(custAbilityList); // 填加新功能
		*/	
		computeDimension(authProcess.getCustId(), authItem);// 计算维度
	}

	/**
	 * 未获取的能力
	 * 
	 * @param custId
	 * @return
	 */
	public Map<Long, Ability> findNotGetAbility(Long custId) {
		Map<Long, Ability> total = abilityService.findAll();
		List<CustAbility> list = custAbilityService.findByCustId(custId);
		for (CustAbility custAbility : list) {
			total.remove(custAbility.getAbilityId());
		}
		return total;
	}

	/**
	 * 计算维度
	 * 
	 * @param custId
	 * @param item
	 * @return
	 */
	public void computeDimension(Long custId, AuthItem item) {
		List<ItemDimension> list = itemDimensionService.findAll();
		List<ItemDimension> correlationList = new ArrayList<ItemDimension>();// 完成项相关的维度
		for (ItemDimension obj : list) {
			if (obj.getItemId().equals(item.getItemId()))
				correlationList.add(obj);
		}
		for (ItemDimension obj : correlationList) {
			CustDimension custDimension = new CustDimension();
			custDimension.setCustId(custId);
			custDimension.setDimensionId(obj.getDimensionId());
			custDimension.setResultTime(new Date());
			List<CustDimension> ret = custDimensionService.find(custId, obj.getDimensionId());
			if (!ret.isEmpty()) {
				custDimensionService.updateForDimension(custDimension);
			} else {
				custDimension.setDemensionScore(obj.getWeight() * item.getItemBasescore() / 100);
				custDimensionService.insert(custDimension);
			}
		}
	}

	@Override
	public void itemExpired(AuthItem item, Long processId) throws Exception {
		AuthItem authItem = authItemService.getItemByCode(item.getAuthCode());
		AuthProccess authProcess = authProccessService.findByIdForUpdate(processId);
		if ((authProcess.getSuccessCode() & authItem.getAuthCode()) != authItem.getAuthCode()) {
			return;
		}
		int successCode = authProcess.getSuccessCode() ^ authItem.getAuthCode();
		authProcess.setSuccessCode(successCode);
		authProccessService.updateProcess(authProcess);
	}
	
	public void addAbility(Long privilegeId,Long custId){
		CustAbility custAbility = new CustAbility();
		custAbility.setCustId(custId);
		custAbility.setAbilityId(privilegeId);
		List<CustAbility> list = custAbilityService.find(custAbility);
		custAbility.setAbilityGettime(new Date());
		Calendar ca = Calendar.getInstance();    
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date expireDate = ca.getTime();
        String expireDateStr = ConcurrentDateUtil.format(expireDate);
        custAbility.setAbilityExpiretime(expireDateStr);
		if(list.size()>0){
			custAbility.setCustAbilityId(list.get(0).getCustAbilityId());
			custAbilityService.update(custAbility);
		}else{
			custAbilityService.insert(custAbility);
		}				
	}
}
